# Copyright 2004 Daniel Henninger <jadestorm@nc.rr.com>
# Licensed for distribution under the GPL version 2, check COPYING for details

from twisted.internet import reactor, base
from tlib import toc
from twisted.python import log
from tlib.im import tocsupport as ts
import config
import utils
import debug
import xdb

class AIMHandler(toc.TOCClient):
	def gotConfig(self, mode, buddylist, permit, deny):
		self.session.aimcon = self
		bl = self.getBuddyList()
		if (bl != None):
			self.add_buddy(bl)
		self.signon()
		debug.log("AIMHandler: gotConfig %s for %s" % (self.username,self.session.jabberID))

	def onLine(self):
		debug.log("AIMHandler: onLine")
		tmpjid = config.jid
		if (self.session.registeredmunge):
			tmpjid = tmpjid + "/registered"
		self.session.sendPresence(to=self.session.jabberID, fro=tmpjid)

	def updateBuddy(self,username,online,evilness,signontime,idletime,userclass,away):
		from glue import aim2jid

		debug.log("AIMHandler: updateBuddy %s" % (username))
		buddyjid = aim2jid(username)
		if (away):
			show = "away"
		else:
			show = None
		status = None
		ptype = None
		self.session.sendPresence(to=self.session.jabberID, fro=buddyjid, show=show, status=status, ptype=ptype)
		if (self.session.aimcontacts.count(buddyjid)):
			debug.log("AIMHandler: updateBuddy %s already in contact list" % (buddyjid))
		else:
			debug.log("AIMHandler: updateBuddy appending %s to contact list" % (buddyjid))
			self.session.aimcontacts.append(buddyjid)

	def hearMessage(self, username, message, autoreply):
		from glue import aim2jid
		debug.log("AIMHandler: hearMessage %s %s" % (username, message))

		sourcejid = aim2jid(username)
		text = ts.dehtml(message)
		text = text.decode("utf-8")
		self.session.sendMessage(to=self.session.jabberID, fro=sourcejid, body=text, mtype="chat")

	def hearWarning(self, warnlvl, screenname):
		debug.log("AIMHandler: hearWarning [%s] from %s" % (warnlvl,screenname))

	def hearError(self, errcode, *args):
		debug.log("AIMHandler: hearError code %d" % (errcode))
		tmpjid = config.jid
		if (self.session.registeredmunge):
			tmpjid = tmpjid + "/registered"
		self.session.sendMessage(to=self.session.jabberID, fro=tmpjid, body=toc.STD_MESSAGE[errcode], mtype="chat")
		self.session.removeMe()

	# Helper functions
	def getBuddyList(self):
		debug.log("AIMHandler: getBuddyList %s %s" % (config.jid, self.session.jabberID))
		bl = list()
		result = self.session.pytrans.xdb.request(self.session.jabberID, "aimtrans:roster")
		if (result == None):
			debug.log("AIMHandler: getBuddyList unable to get list, or empty")
			return None

		for child in result.childNodes:
			try:
				if(child.tagName == "buddies"):
					for item in child.childNodes:
						try:
							if(item.tagName == "item"):
								bl.append(item.attributes["name"])
						except AttributeError:
							continue
			except AttributeError:
				continue

		return bl


class AIMConnection:
	def __init__(self, username, password):
		self.username = username
		self.password = password
		self.session.aimcontacts = list()
		self.host = "toc.oscar.aol.com"
		self.port = 9898
		debug.log("AIMConnection: client creation for %s" % (self.session.jabberID))
		#self.handler = AIMHandler(self.username, self.password)
		self.handler = AIMHandler
		self.handler.session = self.session
		self.factory = base.BCFactory(self.handler(self.username, self.password))
		debug.log("AIMConnection: connect tcp")
		self.reactor = reactor.connectTCP(self.host, self.port, self.factory)

		debug.log("AIMConnection: \"%s\" created" % (self.username))
	
	def setAway(self, awayMessage=None):
		debug.log("AIMConnection: setAway %s" % (awayMessage))

		if (not hasattr(self.session, "aimcontacts")):
			return

		if (not hasattr(self.session, "aimcon")):
			return

		awymsg = ""
		if (awayMessage):
			awymsg = awayMessage

		self.session.aimcon.away(awymsg)

	def sendMessage(self, target, message):
		from glue import jid2aim

		scrnname = jid2aim(target)
		#htmlized = ts.html(utils.latin1(message))
		debug.log("AIMConnection: sendMessage %s %s" % (scrnname, message))
		if (hasattr(self.session, "aimcon")):
			self.session.aimcon.say(scrnname, message.encode("cp1252", "replace"))
		else:
			debug.log("AIMConnection: not properly logged in")
			return

	def resendBuddies(self, resource):
		debug.log("AIMConnection: resendBuddies %s" % (resource))
		if (not hasattr(self.session, "aimcontacts")):
			return

		for c in self.session.aimcontacts:
			debug.log("AIMConnection: resending buddy of %s" % (c))
			show = None
			status = None
			ptype = "available"
			self.session.sendPresence(to=self.session.jabberID, fro=c, show=show, status=status, ptype=ptype)

	def getvCard(self, vcard, user):
		debug.log("AIMConnection: getvCard %s" % (user))

	def removeMe(self):
		debug.log("AIMConnection: removeMe")
		if (not hasattr(self.session, "aimcontacts")):
			return

		for c in self.session.aimcontacts:
			debug.log("AIMConnection: sending offline for %s" % (c))
			show = None
			status = None
			ptype = "unavailable"
			self.session.sendPresence(to=self.session.jabberID, fro=c, show=show, status=status, ptype=ptype)

	def jabberSubscriptionReceived(self, to, subtype):
		debug.log("AIMConnection: Session \"%s\" - jabberSubscriptionReceived(\"%s\", \"%s\")" % (self.session.jabberID, to, subtype))

		def updatePresence(ptype): # Convenience
			self.session.sendPresence(to=self.session.jabberID, fro=to, ptype=ptype)

		if(to.find('@') > 0): # For contacts
			from glue import jid2aim

			userHandle = jid2aim(to)
			#ssibuddy = oscar.SSIBuddy(userHandle)
			#ssigroup = oscar.SSIGroup("Buddies")

			if(subtype == "subscribe"):
				# User wants to subscribe to contact's presence
				#def cb(arg=None):
				#	updatePresence("subscribed")

				#self.session.aimcon.addItemSSI(ssibuddy).addCallback(cb)
				pass

			elif(subtype == "subscribed"):
				# The user has granted this contact subscription
				pass

			elif(subtype == "unsubscribe"):
				# User wants to unsubscribe to this contact's presence. (User is removing the contact from their list)
				#def cb(arg=None):
				#	updatePresence("unsubscribed")

				#self.session.aimcon.delItemSSI(ssibuddy).addCallback(cb)
				pass

                        elif(subtype == "unsubscribed"):
                                # The user wants to remove this contact's authorisation. Contact will no longer be able to see user
				pass

                else: # The user wants to change subscription to the transport
                        if(subtype == "subscribe"):
                                updatePresence("subscribed")

                        elif(subtype == "subscribed"):
                                return # Nothing to do

                        elif(subtype == "unsubscribe" or subtype == "unsubscribed"):
                                # They want to unregister. Ok, we can do that
                                jid = self.session.jabberID
				debug.log("Subscriptions: Session \"%s\" is about to be unregistered" % (jid))
				self.session.pytrans.registermanager.removeRegInfo(jid)
				debug.log("Subscriptions: Session \"%s\" has been unregistered" % (jid))
